﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Kokomo.Mirror.Ia32
{
	public struct Mnemonic
	{
		public Mnemonic(
			string name,
			OpCodeType type = OpCodeType.Unknown,
			FlowControl flowControl = FlowControl.Normal,
			string[] aliases = null,
			string description = null
			)
			: this(name, description, type, flowControl, aliases)
		{
		}
		public Mnemonic(
			string name,
			string description,
			OpCodeType type,
			FlowControl flowControl = FlowControl.Normal,
			string[] aliases = null
			)
			: this()
		{
			this.Name = name;
			this.Type = type;
			this.FlowControl = flowControl;
			this.Aliases = aliases;
			this.Description = description;
		}

		public override string ToString()
		{
			return this.Name;
		}

		public string Name { get; private set; }
		public OpCodeType Type { get; private set; }
		public FlowControl FlowControl { get; internal set; }
		public string[] Aliases { get; private set; }
		public string Description { get; private set; }

		public static readonly Mnemonic Unknown = new Mnemonic("???");

		#region Processor control
		public static readonly Mnemonic cpuid = new Mnemonic("cpuid", "CPU ID", OpCodeType.Control);

		public static readonly Mnemonic sahf = new Mnemonic("sahf", "Store AH into FLAGS", OpCodeType.Control);
		public static readonly Mnemonic lahf = new Mnemonic("lahf", "Load FLAGS into AH register", OpCodeType.Control);

		public static readonly Mnemonic hlt = new Mnemonic("hlt", "Halt", OpCodeType.Control);

		public static readonly Mnemonic cmc = new Mnemonic("cmc", "Complement carry flag", OpCodeType.Control);
		public static readonly Mnemonic clc = new Mnemonic("clc", "Clear carry flag", OpCodeType.Control);
		public static readonly Mnemonic stc = new Mnemonic("stc", "Set carry flag", OpCodeType.Control);
		public static readonly Mnemonic cli = new Mnemonic("cli", "Clear interrupt flag", OpCodeType.Control);
		public static readonly Mnemonic sti = new Mnemonic("sti", "Set interrupt flag", OpCodeType.Control);
		public static readonly Mnemonic cld = new Mnemonic("cld", "Clear direction flag", OpCodeType.Control);
		public static readonly Mnemonic std = new Mnemonic("std", OpCodeType.Control);

		public static readonly Mnemonic clts = new Mnemonic("clts", "Clear Task-Switched flag", OpCodeType.Control);

		public static readonly Mnemonic ud2 = new Mnemonic("#ud2", "Undefined", OpCodeType.Control);
		public static readonly Mnemonic nop = new Mnemonic("nop", "No operation", OpCodeType.Control);

		public static readonly Mnemonic rdmsr = new Mnemonic("rdmsr", "Read MSR", OpCodeType.Control);
		public static readonly Mnemonic wrmsr = new Mnemonic("wrmsr", "Write MSR", OpCodeType.Control);
		public static readonly Mnemonic rdtsc = new Mnemonic("rdtsc", "Read timestamp counter", OpCodeType.Control);
		public static readonly Mnemonic rdpmc = new Mnemonic("rdpmc", "Read preformance-monitoring", OpCodeType.Control);

		public static readonly Mnemonic rsm = new Mnemonic("rsm", "Resume from SMM", OpCodeType.Control);

		public static readonly Mnemonic lmsw = new Mnemonic("lmsw", "Load machine status word", OpCodeType.Control);
		public static readonly Mnemonic smsw = new Mnemonic("smsw", "Store machine status word", OpCodeType.Control);
		#endregion
		#region Memory
		public static readonly Mnemonic mov = new Mnemonic("mov", "Move", OpCodeType.Memory);
		public static readonly Mnemonic movzx = new Mnemonic("movzx", "Move and zero-extend", OpCodeType.Memory);
		public static readonly Mnemonic movsx = new Mnemonic("movsx", "Move and sign-extend", OpCodeType.Memory);
		public static readonly Mnemonic bound = new Mnemonic("bound", "Check Array Index Against Bounds", OpCodeType.Memory);
		public static readonly Mnemonic arpl = new Mnemonic("arpl", "Adjust RPL Field of Segment Selector", OpCodeType.Memory);
		public static readonly Mnemonic xchg = new Mnemonic("xchg", "Exchange operands", OpCodeType.Memory);
		public static readonly Mnemonic lea = new Mnemonic("lea", "Load effective address", OpCodeType.Memory);
		public static readonly Mnemonic xlatb = new Mnemonic("xlatb", "Table Look-up Translation", OpCodeType.Memory);
		public static readonly Mnemonic cmpxchg = new Mnemonic("cmpxchg", "Compare and exchange", OpCodeType.Memory);
		public static readonly Mnemonic cmpxch8b = new Mnemonic("cmpxch8b", "Compare and Exchange Bytes", OpCodeType.Memory);

		public static readonly Mnemonic lds = new Mnemonic("lds", "Load far pointer to DS", OpCodeType.Memory);
		public static readonly Mnemonic les = new Mnemonic("les", "Load far pointer to ES", OpCodeType.Memory);
		public static readonly Mnemonic lss = new Mnemonic("lss", "Load far pointer to SS", OpCodeType.Memory);
		public static readonly Mnemonic lfs = new Mnemonic("lfs", "Load far pointer to FS", OpCodeType.Memory);
		public static readonly Mnemonic lgs = new Mnemonic("lgs", "Load far pointer to GS", OpCodeType.Memory);

		public static readonly Mnemonic movs = new Mnemonic("movs", "Move data from string to string", OpCodeType.Memory, aliases: new string[] { "movsb", "movsw", "movsd" });
		public static readonly Mnemonic stos = new Mnemonic("stos", "Store string", OpCodeType.Memory, aliases: new string[] { "stosb", "stosw", "stosd" });
		public static readonly Mnemonic lods = new Mnemonic("lods", "Load string", OpCodeType.Memory, aliases: new string[] { "lodsb", "lodsw", "lodsd" });
		public static readonly Mnemonic scas = new Mnemonic("scas", "Scan string", OpCodeType.Memory, aliases: new string[] { "scasb", "scasw", "scasd" });

		public static readonly Mnemonic lar = new Mnemonic("lar", "Load access rights byte", OpCodeType.Memory);
		public static readonly Mnemonic lsl = new Mnemonic("lsl", "Load segment limit", OpCodeType.Memory);

		public static readonly Mnemonic invd = new Mnemonic("invd", "Invalidate interal caches", OpCodeType.Memory);
		public static readonly Mnemonic wbinvd = new Mnemonic("webinvd", "Write back and invalidate cache", OpCodeType.Memory);
		public static readonly Mnemonic invlpg = new Mnemonic("invlpg", "Invalid TLB entry", OpCodeType.Memory);

		public static readonly Mnemonic verr = new Mnemonic("verr", "Verify segment for reading", OpCodeType.Memory);
		public static readonly Mnemonic verw = new Mnemonic("verw", "Verify segment for writing", OpCodeType.Memory);

		public static readonly Mnemonic cmovo = new Mnemonic("cmovo", "Move if over", OpCodeType.Memory);
		public static readonly Mnemonic cmovno = new Mnemonic("cmovno", "Move unless over", OpCodeType.Memory);
		public static readonly Mnemonic cmovb = new Mnemonic("cmovb", "Move if below", OpCodeType.Memory, aliases: new string[] { "cmovc", "cmovnae" });
		public static readonly Mnemonic cmovae = new Mnemonic("cmovae", "Move unless over", OpCodeType.Memory, aliases: new string[] { "cmovnb", "cmovnc" });
		public static readonly Mnemonic cmove = new Mnemonic("cmove", "Move if equal", OpCodeType.Memory, aliases: new string[] { "cmovz" });
		public static readonly Mnemonic cmovne = new Mnemonic("cmovne", "Move unless equal", OpCodeType.Memory, aliases: new string[] { "cmovnz" });
		public static readonly Mnemonic cmovbe = new Mnemonic("cmovbe", "Move unless above", OpCodeType.Memory, aliases: new string[] { "cmovc", "cmovna" });
		public static readonly Mnemonic cmova = new Mnemonic("cmova", "Move if above", OpCodeType.Memory, aliases: new string[] { "cmovnbe" });
		public static readonly Mnemonic cmovs = new Mnemonic("cmovs", "Move if sign", OpCodeType.Memory);
		public static readonly Mnemonic cmovns = new Mnemonic("cmovns", "Move unless sign", OpCodeType.Memory);
		public static readonly Mnemonic cmovp = new Mnemonic("cmovp", "Move if parity", OpCodeType.Memory, aliases: new string[] { "cmovpe" });
		public static readonly Mnemonic cmovnp = new Mnemonic("cmovnp", "Move unless parity", OpCodeType.Memory, aliases: new string[] { "cmovpo" });
		public static readonly Mnemonic cmovl = new Mnemonic("cmovl", "Move if less than", OpCodeType.Memory, aliases: new string[] { "cmovnge" });
		public static readonly Mnemonic cmovge = new Mnemonic("cmovge", "Move if greater than or equal to", OpCodeType.Memory, aliases: new string[] { "cmovnl" });
		public static readonly Mnemonic cmovle = new Mnemonic("cmovle", "Move if less than or equal to", OpCodeType.Memory, aliases: new string[] { "cmovng" });
		public static readonly Mnemonic cmovg = new Mnemonic("cmovg", "Move if greater than", OpCodeType.Memory, aliases: new string[] { "cmovnle" });

		public static readonly Mnemonic lgdt = new Mnemonic("lgdt", "Load GDTR", OpCodeType.Memory);
		public static readonly Mnemonic sgdt = new Mnemonic("sgdt", "Store GDTR", OpCodeType.Memory);
		public static readonly Mnemonic lidt = new Mnemonic("lidt", "Load IDTR", OpCodeType.Memory);
		public static readonly Mnemonic sidt = new Mnemonic("sidt", "Store IDTR", OpCodeType.Memory);
		public static readonly Mnemonic lldt = new Mnemonic("lldt", "Load LDTR", OpCodeType.Memory);
		public static readonly Mnemonic sldt = new Mnemonic("sldt", "Store LDTR", OpCodeType.Memory);
		public static readonly Mnemonic ltr = new Mnemonic("ltr", "Load TR", OpCodeType.Memory);
		public static readonly Mnemonic str = new Mnemonic("str", "Store TR", OpCodeType.Memory);

		public static readonly Mnemonic monitor = new Mnemonic("monitor", "Set up monitor address", OpCodeType.Memory);
		public static readonly Mnemonic mwait = new Mnemonic("mwait", "Monitor wait", OpCodeType.Memory);
		public static readonly Mnemonic swapgs = new Mnemonic("swapgs", "Swap GS base", OpCodeType.Memory);
		#endregion
		#region Arithmetic
		public static readonly Mnemonic add = new Mnemonic("add", "Add", OpCodeType.Arithmetic);
		public static readonly Mnemonic adc = new Mnemonic("adc", "Add with carry", OpCodeType.Arithmetic);
		public static readonly Mnemonic sbb = new Mnemonic("sbb", "Integer subtraction with borrow", OpCodeType.Arithmetic);
		public static readonly Mnemonic daa = new Mnemonic("daa", "Decimal adjust AL after addition", OpCodeType.Arithmetic);
		public static readonly Mnemonic sub = new Mnemonic("sub", "Subtract", OpCodeType.Arithmetic);
		public static readonly Mnemonic das = new Mnemonic("das", "Decimal adjust AL after subtraction", OpCodeType.Arithmetic);
		public static readonly Mnemonic inc = new Mnemonic("inc", "Increment by 1", OpCodeType.Arithmetic);
		public static readonly Mnemonic dec = new Mnemonic("dec", "Decrement by 1", OpCodeType.Arithmetic);
		public static readonly Mnemonic neg = new Mnemonic("neg", "Negate", OpCodeType.Arithmetic);
		public static readonly Mnemonic mul = new Mnemonic("mul", "Unsigned multiply", OpCodeType.Arithmetic);
		public static readonly Mnemonic imul = new Mnemonic("imul", "Signed Multiply", OpCodeType.Arithmetic);
		public static readonly Mnemonic div = new Mnemonic("div", "Unsigned divide", OpCodeType.Arithmetic);
		public static readonly Mnemonic idiv = new Mnemonic("idiv", "Signed divide", OpCodeType.Arithmetic);

		public static readonly Mnemonic aaa = new Mnemonic("aaa", "ASCII adjust after addition", OpCodeType.Arithmetic);
		public static readonly Mnemonic aas = new Mnemonic("aas", "ASCII adjust after subtraction", OpCodeType.Arithmetic);
		public static readonly Mnemonic aam = new Mnemonic("aam", "ASCII Adjust AX After Multiply", OpCodeType.Arithmetic);
		public static readonly Mnemonic aad = new Mnemonic("aad", "ASCII Adjust AX After Divide", OpCodeType.Arithmetic);

		public static readonly Mnemonic xadd = new Mnemonic("xadd", "Exchange and add", OpCodeType.Arithmetic);
		#endregion
		#region Logical
		public static readonly Mnemonic or = new Mnemonic("or", "Logical inclusive OR", OpCodeType.Logical);
		public static readonly Mnemonic and = new Mnemonic("and", "Logical AND", OpCodeType.Logical);
		public static readonly Mnemonic xor = new Mnemonic("xor", "Logical exclusive OR", OpCodeType.Logical);

		public static readonly Mnemonic rol = new Mnemonic("rol", "Rotate left", OpCodeType.Logical);
		public static readonly Mnemonic ror = new Mnemonic("ror", "Rotate right", OpCodeType.Logical);
		public static readonly Mnemonic rcl = new Mnemonic("rcl", "Rotate left with carry", OpCodeType.Logical);
		public static readonly Mnemonic rcr = new Mnemonic("rcr", "Rotate right with carry", OpCodeType.Logical);
		public static readonly Mnemonic shl = new Mnemonic("shl", "Shift left", OpCodeType.Logical);
		public static readonly Mnemonic shr = new Mnemonic("shr", "Shift right", OpCodeType.Logical);
		public static readonly Mnemonic sar = new Mnemonic("sar", "Shift arithmetic right", OpCodeType.Logical);
		public static readonly Mnemonic not = new Mnemonic("not", "One's complement", OpCodeType.Logical);
		public static readonly Mnemonic pinsrw = new Mnemonic("pinsrw", "Insert work", OpCodeType.Logical);

		public static readonly Mnemonic shld = new Mnemonic("shld", "Shift double-precision left", OpCodeType.Logical);
		public static readonly Mnemonic shrd = new Mnemonic("shrd", "Shift double-precision right", OpCodeType.Logical);

		public static readonly Mnemonic bt = new Mnemonic("bt", "Bit test", OpCodeType.Logical);
		public static readonly Mnemonic bts = new Mnemonic("bts", "Bit test and set", OpCodeType.Logical);
		public static readonly Mnemonic btr = new Mnemonic("btr", "Bit test and reset", OpCodeType.Logical);
		public static readonly Mnemonic btc = new Mnemonic("btc", "Bit test and complement", OpCodeType.Logical);
		public static readonly Mnemonic bsf = new Mnemonic("bsf", "Bit scan forward", OpCodeType.Logical);
		public static readonly Mnemonic bsr = new Mnemonic("bsr", "Bit scan reverse", OpCodeType.Logical);

		public static readonly Mnemonic seto = new Mnemonic("seto", "Set if over", OpCodeType.Memory);
		public static readonly Mnemonic setno = new Mnemonic("setno", "Set unless over", OpCodeType.Memory);
		public static readonly Mnemonic setb = new Mnemonic("setb", "Set if below", OpCodeType.Memory, aliases: new string[] { "setnae", "setc" });
		public static readonly Mnemonic setae = new Mnemonic("setae", "Set unless below", OpCodeType.Memory, aliases: new string[] { "setnb", "setnc" });
		public static readonly Mnemonic sete = new Mnemonic("sete", "Set if equal", OpCodeType.Memory, aliases: new string[] { "setz" });
		public static readonly Mnemonic setne = new Mnemonic("setne", "Set unless equal", OpCodeType.Memory, aliases: new string[] { "setnz" });
		public static readonly Mnemonic setbe = new Mnemonic("setbe", "Set unless above", OpCodeType.Memory, aliases: new string[] { "setna" });
		public static readonly Mnemonic seta = new Mnemonic("seta", "Set if above", OpCodeType.Memory, aliases: new string[] { "setnbe" });
		public static readonly Mnemonic sets = new Mnemonic("sets", "Set if sign", OpCodeType.Memory);
		public static readonly Mnemonic setns = new Mnemonic("setns", "Set unless sign", OpCodeType.Memory);
		public static readonly Mnemonic setp = new Mnemonic("setp", "Set if parity", OpCodeType.Memory, aliases: new string[] { "setpe" });
		public static readonly Mnemonic setnp = new Mnemonic("setnp", "Set unless parity", OpCodeType.Memory, aliases: new string[] { "setpo" });
		public static readonly Mnemonic setl = new Mnemonic("setl", "Set if less than", OpCodeType.Memory, aliases: new string[] { "setnge" });
		public static readonly Mnemonic setge = new Mnemonic("setge", "Set if greater than or equal to", OpCodeType.Memory, aliases: new string[] { "setnl" });
		public static readonly Mnemonic setle = new Mnemonic("setle", "Let if less than or equal to", OpCodeType.Memory, aliases: new string[] { "setng" });
		public static readonly Mnemonic setg = new Mnemonic("setg", "Set if greater than", OpCodeType.Memory, aliases: new string[] { "setnle" });
		#endregion
		#region Testing
		public static readonly Mnemonic cmp = new Mnemonic("cmp", "Compare two operands", OpCodeType.Test);
		public static readonly Mnemonic test = new Mnemonic("test", "Logical compare", OpCodeType.Test);
		public static readonly Mnemonic cmps = new Mnemonic("cmps", "Compare string operands", OpCodeType.Logical, aliases: new string[] { "cmpsb", "cmpsw", "cmpsd" });

		#endregion
		#region Stack
		public static readonly Mnemonic push = new Mnemonic("push", "Push value onto stack", OpCodeType.Stack);
		public static readonly Mnemonic pop = new Mnemonic("pop", "Pop value from stack", OpCodeType.Stack);
		public static readonly Mnemonic pushad = new Mnemonic("pushad", "Push all general-purpose registers", OpCodeType.Stack, aliases: new string[] { "pusha" });
		public static readonly Mnemonic popad = new Mnemonic("popad", "Pop all general-purpose registers", OpCodeType.Stack, aliases: new string[] { "pusha" });
		public static readonly Mnemonic pushf = new Mnemonic("pushfd", "Push EFLAGS to stack", OpCodeType.Stack, aliases: new string[] { "pushf" });
		public static readonly Mnemonic popf = new Mnemonic("popfd", "Pop EFLAGS from stack", OpCodeType.Stack, aliases: new string[] { "popf" });

		public static readonly Mnemonic enter = new Mnemonic("enter", "Enter procedure", OpCodeType.Stack);
		public static readonly Mnemonic leave = new Mnemonic("leave", "Leave procedure", OpCodeType.Stack);
		#endregion

		#region I/O
		public static readonly Mnemonic @in = new Mnemonic("in", "Input from port", OpCodeType.IO);
		public static readonly Mnemonic @out = new Mnemonic("out", "Output to port", OpCodeType.IO);
		public static readonly Mnemonic ins = new Mnemonic("ins", "Input string from port", OpCodeType.IO, aliases: new string[] { "insb", "insw", "insd" });
		public static readonly Mnemonic outs = new Mnemonic("outs", "Output string to port", OpCodeType.IO, aliases: new string[] { "outsb", "outsw", "outsd" });

		#endregion
		#region Flow
		public static readonly Mnemonic jmp = new Mnemonic("jmp", "Jump", OpCodeType.Flow, FlowControl.Jump);
		public static readonly Mnemonic jmpf = new Mnemonic("jmpf", "Far jump", OpCodeType.Flow, FlowControl.Jump);

		public static readonly Mnemonic call = new Mnemonic("call", "Call procedure", OpCodeType.Flow, FlowControl.Call);
		public static readonly Mnemonic callf = new Mnemonic("callf", "Far call", OpCodeType.Flow, FlowControl.Call, new string[] { "call" });
		public static readonly Mnemonic ret = new Mnemonic("ret", "Return", OpCodeType.Flow, FlowControl.Return, new string[] { "retn" });
		public static readonly Mnemonic retf = new Mnemonic("retf", "Far return", OpCodeType.Flow, FlowControl.Return);

		public static readonly Mnemonic loopne = new Mnemonic("loopne", "Loop unless equal", OpCodeType.Flow, FlowControl.Loop);
		public static readonly Mnemonic loope = new Mnemonic("loope", "Loop if equal", OpCodeType.Flow, FlowControl.Loop);
		public static readonly Mnemonic loop = new Mnemonic("loop", "Loop", OpCodeType.Flow, FlowControl.Loop);

		public static readonly Mnemonic jo = new Mnemonic("jo", "Jump if overflow", OpCodeType.Flow, FlowControl.ConditionalJump);
		public static readonly Mnemonic jno = new Mnemonic("jno", "Jump unless overflow", OpCodeType.Flow, FlowControl.ConditionalJump);
		public static readonly Mnemonic jb = new Mnemonic("jb", "Jump if below", OpCodeType.Flow, FlowControl.ConditionalJump, aliases: new string[] { "jnae", "jc" });
		public static readonly Mnemonic jae = new Mnemonic("jae", "Jump unless below", OpCodeType.Flow, FlowControl.ConditionalJump, aliases: new string[] { "jnb", "jnc" });
		public static readonly Mnemonic je = new Mnemonic("je", "Jump if equal", OpCodeType.Flow, FlowControl.ConditionalJump, aliases: new string[] { "jz" });
		public static readonly Mnemonic jne = new Mnemonic("jne", "Jump unless equal", OpCodeType.Flow, FlowControl.ConditionalJump, aliases: new string[] { "jnz" });
		public static readonly Mnemonic jbe = new Mnemonic("jbe", "Jump unless above", OpCodeType.Flow, FlowControl.ConditionalJump, aliases: new string[] { "jna" });
		public static readonly Mnemonic ja = new Mnemonic("ja", "Jump if above", OpCodeType.Flow, FlowControl.ConditionalJump, aliases: new string[] { "jnbe" });
		public static readonly Mnemonic js = new Mnemonic("js", "Jump if sign", OpCodeType.Flow, FlowControl.ConditionalJump);
		public static readonly Mnemonic jns = new Mnemonic("jns", "Jump unless sign", OpCodeType.Flow, FlowControl.ConditionalJump);
		public static readonly Mnemonic jp = new Mnemonic("jp", "Jump if parity", OpCodeType.Flow, FlowControl.ConditionalJump, aliases: new string[] { "jpe" });
		public static readonly Mnemonic jnp = new Mnemonic("jnp", "Jump unless parity", OpCodeType.Flow, FlowControl.ConditionalJump, aliases: new string[] { "jpo" });
		public static readonly Mnemonic jl = new Mnemonic("jl", "Jump if less", OpCodeType.Flow, FlowControl.ConditionalJump, aliases: new string[] { "jnge" });
		public static readonly Mnemonic jge = new Mnemonic("jge", "Jump unless less", OpCodeType.Flow, FlowControl.ConditionalJump, aliases: new string[] { "jnl" });
		public static readonly Mnemonic jle = new Mnemonic("jle", "Jump unless greater", OpCodeType.Flow, FlowControl.ConditionalJump, aliases: new string[] { "jng" });
		public static readonly Mnemonic jg = new Mnemonic("jg", "Jump if greater", OpCodeType.Flow, FlowControl.ConditionalJump, aliases: new string[] { "jnle" });
		public static readonly Mnemonic jcxz = new Mnemonic("jcxz", "Jump if CX==0", OpCodeType.Flow, FlowControl.ConditionalJump);

		public static readonly Mnemonic @int3 = new Mnemonic("int 3", "Trigger breakpoint", OpCodeType.Flow);
		public static readonly Mnemonic @int = new Mnemonic("int", "Call to interrupt procedure", OpCodeType.Flow);
		public static readonly Mnemonic into = new Mnemonic("into", "Interrupt on overflow", OpCodeType.Flow);
		public static readonly Mnemonic iret = new Mnemonic("iret", "Return from interrupt", OpCodeType.Flow, FlowControl.Return, new string[] { "iretd" });

		public static readonly Mnemonic syscall = new Mnemonic("syscall", "System call", OpCodeType.Flow, FlowControl.Call);
		public static readonly Mnemonic sysret = new Mnemonic("sysret", "Return from system call", OpCodeType.Flow, FlowControl.Return);

		public static readonly Mnemonic sysenter = new Mnemonic("sysenter", "System enter", OpCodeType.Flow, FlowControl.Call);
		public static readonly Mnemonic sysexit = new Mnemonic("sysexit", "System exit", OpCodeType.Flow, FlowControl.Return);
		#endregion
		#region Conversion
		public static readonly Mnemonic cbw = new Mnemonic("cbw", "Convert Byte to Word", OpCodeType.Conversion);
		public static readonly Mnemonic cwd = new Mnemonic("cwd", "Convert Word to Doubleword", OpCodeType.Conversion);

		#endregion
		#region Fpu
		public static readonly Mnemonic fadd = new Mnemonic("fadd");
		public static readonly Mnemonic fmul = new Mnemonic("fmul");
		public static readonly Mnemonic fcom = new Mnemonic("fcom");
		public static readonly Mnemonic fcomp = new Mnemonic("fcomp");
		public static readonly Mnemonic fsub = new Mnemonic("fsub");
		public static readonly Mnemonic fsubr = new Mnemonic("fsubr");
		public static readonly Mnemonic fdiv = new Mnemonic("fdiv");
		public static readonly Mnemonic fdivr = new Mnemonic("fdivr");
		public static readonly Mnemonic fld = new Mnemonic("fld");
		public static readonly Mnemonic fisttp = new Mnemonic("fisttp");
		public static readonly Mnemonic fst = new Mnemonic("fst");
		public static readonly Mnemonic fstp = new Mnemonic("fstp");
		public static readonly Mnemonic frstor = new Mnemonic("frstor");
		public static readonly Mnemonic fsave = new Mnemonic("fsave");
		public static readonly Mnemonic fstsw = new Mnemonic("fstsw");
		public static readonly Mnemonic fwait = new Mnemonic("fwait", "Wait", OpCodeType.Fpu);
		public static readonly Mnemonic fldenv = new Mnemonic("fldenv");
		public static readonly Mnemonic fldcw = new Mnemonic("fldcw");
		public static readonly Mnemonic fstenv = new Mnemonic("fstenv");
		public static readonly Mnemonic fstcw = new Mnemonic("fstcw");
		public static readonly Mnemonic fnop = new Mnemonic("fnop");
		public static readonly Mnemonic fchs = new Mnemonic("fchs");
		public static readonly Mnemonic fabs = new Mnemonic("fabs");
		public static readonly Mnemonic ftst = new Mnemonic("ftst");
		public static readonly Mnemonic fxam = new Mnemonic("fxam");
		public static readonly Mnemonic f2xm1 = new Mnemonic("f2xm1");
		public static readonly Mnemonic fyl2x = new Mnemonic("fyl2x");
		public static readonly Mnemonic fptan = new Mnemonic("fptan");
		public static readonly Mnemonic fpatan = new Mnemonic("fpatan");
		public static readonly Mnemonic fxtract = new Mnemonic("fxtract");
		public static readonly Mnemonic fprem1 = new Mnemonic("fprem1");
		public static readonly Mnemonic fdecstp = new Mnemonic("fdecstp");
		public static readonly Mnemonic fincstp = new Mnemonic("fincstp");
		public static readonly Mnemonic fxch = new Mnemonic("fxch");
		public static readonly Mnemonic fld1 = new Mnemonic("fld1");
		public static readonly Mnemonic fld2t = new Mnemonic("fld2t");
		public static readonly Mnemonic fld2e = new Mnemonic("fld2e");
		public static readonly Mnemonic fldp1 = new Mnemonic("fldp1");
		public static readonly Mnemonic fldlg2 = new Mnemonic("fldlg2");
		public static readonly Mnemonic fldln2 = new Mnemonic("fldln2");
		public static readonly Mnemonic fldz = new Mnemonic("fldz");
		public static readonly Mnemonic fprem = new Mnemonic("fprem");
		public static readonly Mnemonic fyl2xp1 = new Mnemonic("fyl2xp1");
		public static readonly Mnemonic fsqrt = new Mnemonic("fsqrt");
		public static readonly Mnemonic fsincos = new Mnemonic("fsincos");
		public static readonly Mnemonic frndint = new Mnemonic("frndint");
		public static readonly Mnemonic fscale = new Mnemonic("fscale");
		public static readonly Mnemonic fsin = new Mnemonic("fsin");
		public static readonly Mnemonic fcos = new Mnemonic("fcos");
		public static readonly Mnemonic fcmovb = new Mnemonic("fcmovb");
		public static readonly Mnemonic fcmovbe = new Mnemonic("fcmovbe");
		public static readonly Mnemonic fcmove = new Mnemonic("fcmove");
		public static readonly Mnemonic fcmovu = new Mnemonic("fcmovu");
		public static readonly Mnemonic fucompp = new Mnemonic("fucompp");
		public static readonly Mnemonic fiadd = new Mnemonic("fiadd");
		public static readonly Mnemonic fimul = new Mnemonic("fimul");
		public static readonly Mnemonic ficom = new Mnemonic("ficom");
		public static readonly Mnemonic ficomp = new Mnemonic("ficomp");
		public static readonly Mnemonic fisub = new Mnemonic("fisub");
		public static readonly Mnemonic fisubr = new Mnemonic("fisubr");
		public static readonly Mnemonic fidiv = new Mnemonic("fidiv");
		public static readonly Mnemonic fidivr = new Mnemonic("fidivr");
		public static readonly Mnemonic fcmovnb = new Mnemonic("fcmovnb");
		public static readonly Mnemonic fcmovnbe = new Mnemonic("fcmovnbe");
		public static readonly Mnemonic fclex = new Mnemonic("fclex");
		public static readonly Mnemonic finit = new Mnemonic("finit");
		public static readonly Mnemonic fcomi = new Mnemonic("fcomi");
		public static readonly Mnemonic fcmovne = new Mnemonic("fcmovne");
		public static readonly Mnemonic fcmovnu = new Mnemonic("fcmovnu");
		public static readonly Mnemonic fucomi = new Mnemonic("fucomi");
		public static readonly Mnemonic fild = new Mnemonic("fild");
		public static readonly Mnemonic fist = new Mnemonic("fist");
		public static readonly Mnemonic fistp = new Mnemonic("fistp");
		public static readonly Mnemonic ffree = new Mnemonic("ffree");
		public static readonly Mnemonic fucom = new Mnemonic("fucom");
		public static readonly Mnemonic fucomp = new Mnemonic("fucomp");

		#endregion
		#region XMM
		public static readonly Mnemonic movups = new Mnemonic("movups");
		public static readonly Mnemonic movlps = new Mnemonic("movlps");
		public static readonly Mnemonic unpcklps = new Mnemonic("unpcklps");
		public static readonly Mnemonic unpckhps = new Mnemonic("unpckhps");
		public static readonly Mnemonic movhps = new Mnemonic("movhps");
		public static readonly Mnemonic movaps = new Mnemonic("movaps");
		public static readonly Mnemonic cvtpi2ps = new Mnemonic("cvtpi2ps");
		public static readonly Mnemonic movntps = new Mnemonic("movntps");
		public static readonly Mnemonic cvttps2pi = new Mnemonic("cvttps2pi");
		public static readonly Mnemonic cvtps2pi = new Mnemonic("cvtps2pi");
		public static readonly Mnemonic ucomiss = new Mnemonic("ucomiss");
		public static readonly Mnemonic comiss = new Mnemonic("comiss");
		public static readonly Mnemonic movmskps = new Mnemonic("movmskps");
		public static readonly Mnemonic sqrtps = new Mnemonic("sqrtps");
		public static readonly Mnemonic rsqrtps = new Mnemonic("rsqrtps");
		public static readonly Mnemonic rcpps = new Mnemonic("rcpps");
		public static readonly Mnemonic andps = new Mnemonic("andps");
		public static readonly Mnemonic andnps = new Mnemonic("andnps");
		public static readonly Mnemonic orps = new Mnemonic("orps");
		public static readonly Mnemonic xorps = new Mnemonic("xorps");
		public static readonly Mnemonic addps = new Mnemonic("addps");
		public static readonly Mnemonic mulps = new Mnemonic("mulps");
		public static readonly Mnemonic cvtps2pd = new Mnemonic("cvtps2pd");
		public static readonly Mnemonic cvtdq2ps = new Mnemonic("cvtdq2ps");
		public static readonly Mnemonic subps = new Mnemonic("subps");
		public static readonly Mnemonic minps = new Mnemonic("minps");
		public static readonly Mnemonic divps = new Mnemonic("divps");
		public static readonly Mnemonic maxps = new Mnemonic("maxps");
		public static readonly Mnemonic punpcklbw = new Mnemonic("punpcklbw");
		public static readonly Mnemonic punpcklwd = new Mnemonic("punpcklwd");
		public static readonly Mnemonic punpckldq = new Mnemonic("punpckldq");
		public static readonly Mnemonic packsswd = new Mnemonic("packsswd");
		public static readonly Mnemonic pcmpgtb = new Mnemonic("pcmpgtb");
		public static readonly Mnemonic pcmpgtw = new Mnemonic("pcmpgtw");
		public static readonly Mnemonic pcmpgtd = new Mnemonic("pcmpgtd");
		public static readonly Mnemonic packuswb = new Mnemonic("packuswb");
		public static readonly Mnemonic punpckhbw = new Mnemonic("punpckhbw");
		public static readonly Mnemonic punpckhwd = new Mnemonic("punpckhwd");
		public static readonly Mnemonic punpckhdq = new Mnemonic("punpckhdq");
		public static readonly Mnemonic packssdw = new Mnemonic("packssdw");
		public static readonly Mnemonic punpcklqdq = new Mnemonic("punpcklqdq");
		public static readonly Mnemonic punpckhqdq = new Mnemonic("punpckhqdq");
		public static readonly Mnemonic pshufw = new Mnemonic("pshufw");
		public static readonly Mnemonic pcmpeqb = new Mnemonic("pcmpeqb");
		public static readonly Mnemonic pcmpeqw = new Mnemonic("pcmpeqw");
		public static readonly Mnemonic pcmpeqd = new Mnemonic("pcmpeqd");
		public static readonly Mnemonic emms = new Mnemonic("emms");
		public static readonly Mnemonic haddps = new Mnemonic("haddps");
		public static readonly Mnemonic hsubps = new Mnemonic("hsubps");
		public static readonly Mnemonic psrlw = new Mnemonic("psrlw");
		public static readonly Mnemonic psraw = new Mnemonic("psraw");
		public static readonly Mnemonic psllw = new Mnemonic("psllw");
		public static readonly Mnemonic psrld = new Mnemonic("psrld");
		public static readonly Mnemonic psrad = new Mnemonic("psrad");
		public static readonly Mnemonic pslld = new Mnemonic("pslld");
		public static readonly Mnemonic psrlq = new Mnemonic("psrlq");
		public static readonly Mnemonic psrldq = new Mnemonic("psrldq");
		public static readonly Mnemonic psllq = new Mnemonic("psllq");
		public static readonly Mnemonic pslldq = new Mnemonic("pslldq");
		public static readonly Mnemonic cmpps = new Mnemonic("cmpps");
		public static readonly Mnemonic movnti = new Mnemonic("movnti");
		#endregion
		#region VMX
		public static readonly Mnemonic vmread = new Mnemonic("vmread", "Read field from VMCS", OpCodeType.Vmx);
		public static readonly Mnemonic vmwrite = new Mnemonic("vmwrite", "Write field to in VMCS", OpCodeType.Vmx);
		public static readonly Mnemonic vmclear = new Mnemonic("vmclear", "Clear VMCS", OpCodeType.Vmx);
		public static readonly Mnemonic vmxon = new Mnemonic("vmxon", "Enter VMX operation", OpCodeType.Vmx);
		public static readonly Mnemonic vmxoff = new Mnemonic("vmxoff", "Leave VMX operation", OpCodeType.Vmx);
		public static readonly Mnemonic vmptrld = new Mnemonic("vmptrld", "Load VMCS pointer", OpCodeType.Vmx);
		public static readonly Mnemonic vmptrst = new Mnemonic("vmptrst", "Store VMCS pointer", OpCodeType.Vmx);
		public static readonly Mnemonic vmcall = new Mnemonic("vmcall", "Call to VM monitor", OpCodeType.Vmx);
		public static readonly Mnemonic vmlaunch = new Mnemonic("vmlaunch", "Launch virtual machine", OpCodeType.Vmx);
		public static readonly Mnemonic vmresume = new Mnemonic("vmresume", "Resume virtual machine", OpCodeType.Vmx);

		#endregion
	}
}
